package com.quanyan.ic.protocol.server.handler;

import com.quanyan.ic.cache.OrderMsgDao;
import com.quanyan.ic.common.model.OrderMessage;
import com.quanyan.ic.model.FailedOrderMessage;
import com.quanyan.ic.protocol.Code;
import com.quanyan.ic.protocol.LightCmd;
import com.quanyan.ic.protocol.MessageType;
import com.quanyan.ic.protocol.codec.protobuf.ICMessageProto;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * Created by zhuo.shi on 2017/6/5.
 */
@Component("lightCmdRespHandler")
@ChannelHandler.Sharable
public class LightCmdRespHandler extends ChannelInboundHandlerAdapter {

    private Logger logger = LoggerFactory.getLogger(LightCmdRespHandler.class);

    @Autowired
    private OrderMsgDao orderMsgDao;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ICMessageProto.ICMessage icMessage = (ICMessageProto.ICMessage) msg;
        if (icMessage.getHeader() != null) {
            if (icMessage.getHeader().getType() == MessageType.SERVICE_RESP.value()) {
                logger.info("server received Cmd msg: {} from [{}] ", icMessage, ctx.channel().remoteAddress());
                ctx.executor().submit(new CmdProcessor(icMessage));
            } else if (icMessage.getHeader().getType() == MessageType.LIGHTSTATUS_REQ.value()) {
//                logger.info("server receive query light status msg: {} from [{}]",icMessage,ctx.channel().remoteAddress());
//                int placeId = icMessage.getHeader().getPid();
//                int siteId = icMessage.getBody().getSid();
//                Byte lightStatus = placeLightSettingDao.getLightStatus(siteId);
//                Code respStatus = Code.RC_200;
//                if(null == lightStatus){
//                    lightStatus = (byte)-1;
//                    respStatus = Code.RC_203;
//                    placeLightSettingDao.setLightStatus(siteId, LightCmd.OFF.value());
//                }
//                ctx.writeAndFlush(ICMessageBuilder.buildLightStatusMessage(icMessage.getHeader().getPid(),icMessage.getBody().getSid(),lightStatus,respStatus));
//                logger.info("server send light status msg : {} to [{}]",ICMessageBuilder.buildLightStatusMessage(placeId,siteId,lightStatus,respStatus),ctx.channel().remoteAddress());
            }
        } else {
            ctx.fireChannelRead(msg);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if (cause.getMessage().startsWith("Connection reset")
                && (ctx.channel().remoteAddress().toString().startsWith("/10.") || ctx.channel().remoteAddress().toString().startsWith("/100."))) {
            logger.info("health check!");
            return;
        }
        ctx.fireExceptionCaught(cause);
    }

    private class CmdProcessor implements Runnable {

        private Logger logger = LoggerFactory.getLogger(CmdProcessor.class);

        private ICMessageProto.ICMessage icMessage;

        protected CmdProcessor(ICMessageProto.ICMessage icMessage) {
            this.icMessage = icMessage;
        }

        @Override
        public void run() {
            //记录开关灯状态
            ICMessageProto.ICMessage.Body body = icMessage.getBody();
            int rc = icMessage.getHeader().getRespCode();
            int sc = body.getSc();       //开关灯是否成功

            //记录反馈
            String orderNo = icMessage.getBody().getOrderNo();
            int pid = icMessage.getHeader().getPid();
            int sid = icMessage.getBody().getSid();
            orderMsgDao.saveLightCmdMsg(icMessage.toString());

            OrderMessage orderMessage = new OrderMessage();
            orderMessage.setOrderNo(orderNo);
            orderMessage.setPlaceId(pid);
            orderMessage.setSiteId(sid);
            orderMessage.setStartTime(body.getStime());
            orderMessage.setEndTime(body.getEtime());
            orderMessage.setCurrentTime(null);
            orderMessage.setOrderStatus((byte) body.getOrderStatus());
            orderMessage.setSiteType(body.getSiteType());

            LightCmd cmd = body.getTf() == 0 ? LightCmd.OFF : LightCmd.ON;
            //开关灯，成功，删除failed集合中删除
            if (rc == Code.RC_200.value() && sc == Code.SC_300.value()) {
//                orderMsgDao.delFailedChannelMsg(orderNo, pid, sid, body.getStime(), body.getEtime());
//                List<FailedOrderMessage> delMsg = new ArrayList<>();
//                FailedOrderMessage fmsg = FailedOrderMessage.build(orderMessage, cmd);
//                delMsg.add(fmsg);
                orderMsgDao.removeFailedOrderMsg(pid, sid, cmd);
            } else {
                if (!StringUtils.isEmpty(orderNo) && !"BLANK".equals(orderNo)) {
                    orderMsgDao.saveFailedChannelMsg(FailedOrderMessage.build(orderMessage, cmd));
                    logger.warn("client [{}], execute light Cmd error: code={}, msg={}, save to failed msg queue", pid, sc, body.getMsg());
                } else {
                    logger.info("execute light Cmd by manual, failed, ignore!");
                }
            }
        }
    }

}
